package handles

import (
	"errors"
	"github.com/Sir-yuChen/funAnalyse/global"
	"github.com/Sir-yuChen/funAnalyse/global/constant"
	"github.com/Sir-yuChen/funAnalyse/model"
	"go.uber.org/zap"
	"time"
)

//定时任务公用方法

// TimerHandlePreOperation 定时任务处理方法的前置操作 主要对定时任务的校验等
func TimerHandlePreOperation(handleName string, taskId int, task model.StockTImer) (taskDB model.StockTImer, err error) {
	taskDB, err = GetTimerInfo(task.UniqueCode)
	if err != nil {
		return taskDB, err
	}
	//修改执行状态
	err = UpdateTimerExecutionStatus(taskDB.UniqueCode, constant.TIMER_ExecutionStatus_in_run)
	if err != nil {
		return taskDB, err
	}
	//校验任务时间区间

	f := ConfirmTimerPeriod(taskDB.TimerStartTime.ToTime(), taskDB.TimerEndTime.ToTime(), taskDB.UniqueCode, taskId)
	if !f {
		UpdateTimerExecutionStatus(taskDB.UniqueCode, constant.TIMER_ExecutionStatus_executed_fail)
		if taskDB.TimerType == constant.TIMER_TASK_TYPE_disposable { //一次性任务
			UpdateTimerStatus(taskDB.UniqueCode, constant.STATUS_N)
			StopAndRemoveTimer(taskDB.UniqueCode, taskId) //停止清除任务
		}
		//todo 推报警信息
		global.GVA_LOG.Error(handleName+" Run 开始结束时间校验未通过", zap.Any("StockTImer", taskDB))
		return taskDB, errors.New("开始/结束时间校验未通过")
	}
	//校验任务状态  任务状态，执行状态 todo
	if taskDB.Status != constant.STATUS_Y {
		global.GVA_LOG.Error(handleName+" Run 当前任务不正常,无法执行", zap.Any("StockTImer", taskDB))
		return taskDB, errors.New("当前任务状态非正常,无法执行")
	}
	return taskDB, err
}

// TimerHandlePostOperation 定时任务后置操作 校验任务是否为一次性任务，是否已过期 ，修改任务状态，清除任务列表
func TimerHandlePostOperation(handleName string, taskId int, taskDB model.StockTImer, err error) error {
	//校验是否是一次性任务
	executionStatus := constant.TIMER_ExecutionStatus_executed_sucess
	if err != nil {
		executionStatus = constant.TIMER_ExecutionStatus_executed_fail
	}
	err = UpdateTimerExecutionStatus(taskDB.UniqueCode, executionStatus)
	if err != nil {
		return err
	}
	if taskDB.TimerType == constant.TIMER_TASK_TYPE_disposable {
		err = UpdateTimerStatus(taskDB.UniqueCode, constant.STATUS_N)
		if err != nil {
			return err
		}
		StopAndRemoveTimer(taskDB.UniqueCode, taskId) //停止清除任务
	}

	return err
}

// ConfirmTimerPeriod 确认定时任务时间区间
func ConfirmTimerPeriod(start time.Time, end time.Time, uniqueCode string, taskId int) bool {
	f := false
	nowTime, _ := time.Parse("2006-01-02 15:04:05", time.Now().Format("2006-01-02 15:04:05"))
	f = nowTime.After(start)
	if !f {
		global.GVA_LOG.Error("当时任务开始时间大于当前时间", zap.Any("uniqueCode", uniqueCode), zap.Any("startTime", start))
		return f
	}
	f = nowTime.Before(end)
	if !f {
		global.GVA_LOG.Error("当时任务结束时间小于当前时间", zap.Any("uniqueCode", uniqueCode), zap.Any("endTime", end))
		if err := UpdateTimerStatus(uniqueCode, constant.STATUS_N); err != nil {
			return f
		}
		StopAndRemoveTimer(uniqueCode, taskId) //停止清除任务
		return f
	}
	return f
}

// UpdateTimerExecutionStatus 修改任务执行状态
func UpdateTimerExecutionStatus(uniqueCode string, timerExeStatus int) error {
	if err := global.GVA_DB.Model(&model.StockTImer{}).Where("unique_code = ? ", uniqueCode).Update("execution_status", timerExeStatus).Error; err != nil {
		global.GVA_LOG.Error("修改定时任务执行状态异常", zap.Any("uniqueCode", uniqueCode), zap.Any("timerExeStatus", timerExeStatus), zap.Error(err))
		return err
	}
	return nil
}

// UpdateTimerStatus 修改任务状态
func UpdateTimerStatus(uniqueCode string, timerStatus string) error {
	if err := global.GVA_DB.Model(&model.StockTImer{}).Where("unique_code = ? ", uniqueCode).Update("status", timerStatus).Error; err != nil {
		global.GVA_LOG.Error("修改定时任务状态异常", zap.Any("uniqueCode", uniqueCode), zap.Any("timerExeStatus", timerStatus), zap.Error(err))
		return err
	}
	return nil
}

// GetTimerInfo 获取定时任务详情
func GetTimerInfo(uniqueCode string) (m model.StockTImer, e error) {
	var mo model.StockTImer
	if err := global.GVA_DB.Model(&model.StockTImer{}).Where("unique_code = ? ", uniqueCode).First(&mo).Error; err != nil {
		global.GVA_LOG.Error("获取定时任务详情异常", zap.Any("uniqueCode", uniqueCode), zap.Error(err))
		return mo, err
	}
	return mo, nil
}

// StopAndRemoveTimer   停止任务和清除任务
func StopAndRemoveTimer(uniqueCode string, taskId int) {
	_, b := global.GVA_Timer.FindCron(uniqueCode)
	if b {
		global.GVA_Timer.StopTask(uniqueCode) //停止
		global.GVA_Timer.Remove(uniqueCode, taskId)
		global.GVA_LOG.Error("定时任务清除成功", zap.Any("uniqueCode", uniqueCode))
	}
}
